// ts的基本类型约束
// number类型：数值类型。
let m: number = 10;
m = 200;
console.log(m);

// ts类型检测：在代码编译阶段就开始检查了，而不是等到代码运行阶段才检查。但是，ts的检查结果是不影响最终编译的js代码的，因为所有不合法的ts代码在js里面都是合法的，浏览器执行js都会通过。
function sum(a: number, b: number) {
  console.log(a + b);
}
sum(30, 40);

// 函数返回值类型的约束，直接影响接收这个值的变量。
function sum1(a: number, b: number): number {
  return a + b;
}
const res: number = sum1(130, 140);
console.log(res);

// 布尔类型
let isMan: boolean = true;
isMan = false;
console.log("---isMan: ", isMan);

// 字符串类型
let userName: string = "";
userName = "小明";
console.log("---userName: ", userName);

// 数组类型
let users: number[] = [1, 2, 3, 4, 5];
console.log("---users: ", users);
let users1: string[] = ["1", "2", "3"];

// 联合类型：由多个基本数据类型组合起来形成的一种类型
let users2: (number | string | boolean)[] = ["1", 22, true, false, 22];

// 数组类型写法一：类型[]
// 数组类型写法二：Array<类型>
// 注：类型可以是单一类型，也可以是联合类型。
let users3: Array<number> = [1, 2, 3, 4];
let users4: Array<string> = ["1", "2", "3"];
let users5: Array<number | string | boolean> = ["1", "2", 20, true];
users5.push(2000);
console.log(users5);

// 联合类型：使用|符合表示一个变量可以是多种类型。
let result: number | boolean | string = "2332";

// 元组类型：一个数据类型和个数已经固定了的数组，后期也能新增，删除，修改。
// [string, number, boolean] 元组类型
let tData: [string, number, boolean, number, number, number, number, number] = [
  "11",
  10,
  true,
  100,
  300,
  400,
  500,
  600,
];
tData.push("1000");
console.log(tData[0], tData);

// 枚举类型：它一般用来设置一些常量数据，声明出来的值后续不会发生变化，只拿来使用。

// Sex和Classes就是两个枚举类型。
enum Sex {
  man = "男人",
  women = "女人",
}

enum Classes {
  one = "1班",
  two = "2班",
  three = "3班",
  four = "4班",
}
console.log(Sex.man);

// Any类型：任意类型，使用它标识变量，就是让ts编译器忽略这个变量，不检查类型，直接编译成js。一般用在无法确定类型的情况下使用。
let result2: any = "";
result2 = 100;
result2 = "100";

// void类型：空类型，用在函数的返回值。表示函数没有返回值。
function sum2(): void {
  console.log("----");
}
sum2();

// null和undefined类型：它两也是一种类型，和string, number一样，都是类型。可以用作初始值。
let result3: string | undefined = undefined;
result3 = "小王";

let result4: number[] | null = null;
result4 = [1, 2, 3, 4];

// 类型断言：强制告诉ts编译器，这个变量是什么类型。在一些复杂的场景下，ts已经无法准确推断变量类型了。
// 两种语法：(<断言类型>result5) (result5 as 断言类型)
let result5: unknown;
(<number[]>result5).forEach(item => {
  console.log(item);
});
(result5 as number[]).forEach(item => {
  console.log(item);
});
